package com.slj.springcloud.controller;

import com.slj.springcloud.model.response.Result;
import com.slj.springcloud.service.ResilienceService;
import io.github.resilience4j.bulkhead.annotation.Bulkhead;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/order/resilience")
@Slf4j
public class OrderResilienceController {
    @Autowired
    private ResilienceService circuitService;

    @GetMapping("/circuit")
    public Result<String> circuit(@RequestParam("id") Long id) {
        return Result.success(circuitService.circuit(id));
    }


    @GetMapping("/bulkhead/semaphore")
    @Bulkhead(name = "cloud-order", fallbackMethod = "bulkheadSemaphoreFallBack", type = Bulkhead.Type.SEMAPHORE)
    public Result<String> bulkheadSemaphore() throws InterruptedException {
        log.info("************** 进入方法 *******");
        TimeUnit.SECONDS.sleep(10);
        log.info("************** 离开方法 *******");
        return Result.success("bulkhead...ok");
    }


    @GetMapping("/bulkhead/thread")
    @Bulkhead(name = "cloud-order", fallbackMethod = "bulkheadThreadFallBack", type = Bulkhead.Type.THREADPOOL)
    public CompletableFuture<Result<String>> bulkheadThread() throws InterruptedException {
        log.info("************** 进入方法 *******");
        TimeUnit.SECONDS.sleep(10);
        log.info("************** 离开方法 *******");
        return CompletableFuture.supplyAsync(() -> Result.success("bulkhead...ok"));
    }

    @GetMapping("/ratelimiter")
    @RateLimiter(name = "cloud-pay", fallbackMethod = "ratelimiterFallBack")
    public Result<String> ratelimiter() throws InterruptedException {
        log.info("************** 进入方法 *******");
        TimeUnit.SECONDS.sleep(10);
        log.info("************** 离开方法 *******");
        return Result.success("ratelimiter...ok");
    }

    private Result<String> bulkheadSemaphoreFallBack(Throwable throwable) {
        log.error(throwable.getMessage());
        return Result.success("信号量隔板超出限制");
    }

    private CompletableFuture<Result<String>> bulkheadThreadFallBack(Throwable throwable) {
        log.error(throwable.getMessage());
        return CompletableFuture.supplyAsync(() -> Result.success("线程超出隔板限制"));
    }

    private Result<String> ratelimiterFallBack(Throwable throwable) {
        log.error(throwable.getMessage());
        return Result.success("被限流了");
    }
}
